package logs

import (
	"fmt"
	"log"
	"runtime"
	"strings"
)

func init() {
	// log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)
}

// see https://www.cnblogs.com/goloving/p/15015053.html
const (
	RESET   = "\x1b[0m"
	RED     = "\x1b[31m"
	GREEN   = "\x1b[32m"
	YELLOW  = "\x1b[33m"
	BLUE    = "\x1b[34m"
	MAGENTA = "\x1b[35m" // 紫色
	CYAN    = "\x1b[36m" // 蓝绿
	WHITE   = "\x1b[37m"
)

var (
	logLevel = int32(0)
	logColor = true
)

func Init(level int32, color bool) {
	logLevel = level
	logColor = color
}

func Debug(format any, params ...any) {
	if logLevel > 0 {
		return
	}
	write("D", WHITE, format, params...)
}

func Info(format any, params ...any) {
	if logLevel > 1 {
		return
	}
	write("I", WHITE, format, params...)
}

func Warn(format any, params ...any) {
	if logLevel > 2 {
		return
	}
	write("W", YELLOW, format, params...)
}

func Error(format any, params ...any) {
	if logLevel > 3 {
		return
	}
	write("E", RED, format, params...)
	logStack(2)
}

func Major(format any, params ...any) {
	if logLevel > 3 {
		return
	}
	write("M", MAGENTA, format, params...)
	logStack(2)
}

func write(level string, color string, format any, params ...any) {
	_, file, line, _ := runtime.Caller(2)

	// mp := os.Args[0]
	// mp = strings.Replace(mp, "\\", "/", -1)
	// mp = mp[:strings.LastIndex(mp, "/")]
	// log.Print(mp)
	// file = strings.Replace(file, mp, "", 1)

	var logstr string
	switch format.(type) {
	case string:
		logstr = fmt.Sprintf(format.(string), params...)
	default:
		if len(params) < 1 {
			logstr = fmt.Sprintf("%v", format)
		} else {
			temp := make([]any, 0, len(params)+1)
			temp = append(temp, format)
			temp = append(temp, params...)
			logstr = fmt.Sprintf(strings.Repeat("%v ", len(temp)), temp...)
		}
	}

	writeLine(level, color, file, line, logstr)
}

func writeLine(tag string, color string, file string, line int, msg string) {
	if logColor {
		if msg == "" {
			log.Printf("%s[%s] %s:%d%s", color, tag, file, line, RESET)
		} else {
			log.Printf("%s[%s] %s:%d %s%s", color, tag, file, line, msg, RESET)
		}
	} else {
		if msg == "" {
			log.Printf("[%s] %s:%d", tag, file, line)
		} else {
			log.Printf("[%s] %s:%d %s", tag, file, line, msg)
		}

	}
}

func logStack(skip int32) {
	for i := int(skip); ; i++ {
		_, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		writeLine("S", CYAN, file, line, "")
	}
}

func LogStack() {
	logStack(2)
}
